import AgoraRTC from 'agora-rtc-sdk'
import EventEmitter from 'events'

let client = AgoraRTC.createClient({ mode: "rtc", codec: "vp8" });
let localStream = null;
export default class RTCClient {
    constructor() {
        this.option = {
            appId: '',
            channel: '',
            uid: '',
            token: '',
        }
        this.client = client
        this._eventBus = new EventEmitter()
    }

    joinChannel(option) {
        return new Promise((resolve, reject) => {
            client = AgoraRTC.createClient({ mode: "rtc", codec: "vp8" })
            client.init(option.appid, () => {
                console.log("init success")
                this.clientListener()
                client.join(option.token ? option.token : null, option.channel, null, (uid) => {
                    console.log("join channel: " + this.option.channel + " success, uid: ", uid)
                    this.option = {
                        appid: option.appid,
                        token: option.token,
                        channel: option.channel,
                        uid: uid,
                    }
                    resolve()
                }, (err) => {
                    console.error("client join failed", err)
                })
            }, (err) => {
                reject()
                console.error(err)
            })
            console.log("[agora-vue] appId", option.appid)
        })
    }

    publishStream() {
        return new Promise((resolve, reject) => {
            // Create a local stream
            localStream = AgoraRTC.createStream({
                streamID: this.option.uid,
                audio: true,
                video: true,
                screen: false,
            })
            // Initialize the local stream
            localStream.init(() => {
                console.log("init local stream success")
                resolve(localStream)
                // Publish the local stream
                client.publish(localStream, (err) => {
                    console.log("publish failed")
                    console.error(err)
                })
            }, (err) => {
                reject(err)
                console.error("init local stream failed ", err)
            })
        })
    }

    clientListener() {
        client.on('stream-added', (evt) => {
            // The stream is added to the channel but not locally subscribed
            this._eventBus.emit('stream-added', evt)
        })
        client.on('stream-subscribed', (evt) => {
            this._eventBus.emit('stream-subscribed', evt)
        })
        client.on('stream-removed', (evt) => {
            this._eventBus.emit('stream-removed', evt)
        })
        client.on('peer-online', (evt) => {
            this._eventBus.emit('peer-online', evt)
        })
        client.on('peer-leave', (evt) => {
            this._eventBus.emit('peer-leave', evt)
        })
    }

    on(eventName, callback) {
        this._eventBus.on(eventName, callback)
    }

    leaveChannel() {
        return new Promise((resolve, reject) => {
            // Leave the channel
            client.unpublish(localStream, (err) => {
                console.log(err)
            })
            client.leave(() => {
                // Stop playing the local stream
                if (localStream.isPlaying()) {
                    localStream.stop()
                }
                // Close the local stream
                localStream.close()
                client = null
                resolve()
                console.log("client leaves channel success");
            }, (err) => {
                reject()
                console.log("channel leave failed");
                console.error(err);
            })
        })
    }
}